//#include "stdafx.h"
#include "AndNodeModel.h"

CAndNodeModel::CAndNodeModel(void)
{
	AndNodeID		= -1;
	NodeType		= -1;
	LeafIndex		= -1;
	Children.clear();

	AppearanceWeight = 0.0;
}

CAndNodeModel::~CAndNodeModel(void)
{
}

int	CAndNodeModel::MakeMissInformation(ModelTreeType &model, int Level)
{
	int			ChildCount, TripletCount;
	int			ret;

	if (model.List_fIfNodeWork[AndNodeID]) return 1;
	model.List_fIfNodeWork[AndNodeID] = true;

	//this->Level = Level;
	if ( NodeType == 0 )
	{
		MissLeafNode.clear();
		MissLeafNode.push_back(LeafIndex);
		return	1;
	}

	// Miss Score
	ChildCount		= (int) Children.size();
	TripletCount	= (int) triplets.size();
	MissLeafNode.clear();

	for ( int i = 0; i < ChildCount; i++ )
	{
		COrNodeModel	&ChildModel	= model.OrModels[Children[i]];

		ret	= ChildModel.MakeMissInformation(model, Level + 1);
		MissLeafNode.insert(MissLeafNode.end(), ChildModel.MissLeafNode.begin(), ChildModel.MissLeafNode.end());
	}

	// remove dup leaf nodes
	sort(MissLeafNode.begin(), MissLeafNode.end());
	for ( int i = 1; i < (int) MissLeafNode.size(); i++ )
	{
		if ( MissLeafNode[i] == MissLeafNode[i-1] )
		{
			MissLeafNode.erase(MissLeafNode.begin() + i);
			i--;
		}
	}

	return	1;
}

int	CAndNodeModel::SaveAndNodeModel(FILE *fpFile, int RuleCount)
{
	int		ChildCount;

	// general information and children
	ChildCount		= (int)Children.size();

	fprintf_s(fpFile, "::AndNodeModel %02d  \ton_level %d\n", AndNodeID, Level);
	fprintf_s(fpFile, "%12d %12d %12d", NodeType, LeafIndex, ChildCount);
	
	for ( int i = 0; i < RuleCount; i++ )
	{
		fprintf_s(fpFile, " %e", Threshold[i]);
	}
	fprintf_s(fpFile, "\n");

	fprintf_s(fpFile, "%e\n", AppearanceWeight);

	if ( NodeType == 1 )
	{
		for ( int i = 0; i < (int) Children.size(); i++ )
		{
			fprintf_s(fpFile, "%12d ", Children[i]);
		}
		fprintf_s(fpFile, "\n");

		// ChildNode Information
		fprintf_s(fpFile, "%12d\n", ModelCount);
		for ( int i = 0; i < (int) Children.size(); i++ )
		{
			fprintf_s(fpFile, "%12d ", NodeModelIndex[i]);
		}
		fprintf_s(fpFile, "\n");
		for ( int i = 0; i < ModelCount; i++ )
		{
			for ( int j = 0; j < ModelCount; j++ )
			{
				fprintf_s(fpFile, " %12.6f ", NodeLenInfo[i][j]);
			}
			fprintf_s(fpFile, "\n");
		}
		for ( int i = 0; i < ModelCount; i++ )
		{
			for ( int j = 0; j < ModelCount; j++ )
			{
				fprintf_s(fpFile, " %12.6f ", NodeDirInfo[i][j]);
			}
			fprintf_s(fpFile, "\n");
		}

		// triplets
		fprintf_s(fpFile, "%12d\n", (int) triplets.size());
		for ( int i = 0; i < (int) triplets.size(); i++ )
		{
			fprintf_s(fpFile, "%12d %12d %12d ", triplets[i].p1, triplets[i].p2, triplets[i].p3);
			fprintf_s(fpFile, "%12d %12d %12d ", triplets[i].m1, triplets[i].m2, triplets[i].m3);
			fprintf_s(fpFile, " %e\n", triplets[i].gamma);
			fprintf_s(fpFile, " %12d", (int) triplets[i].feature.size());
			for ( int j = 0; j < (int) triplets[i].feature.size(); j++ )
			{
				fprintf_s(fpFile, " %12.6f ", triplets[i].feature[j]);
			}
			for ( int j = 0; j < (int) triplets[i].variance.size(); j++ )
			{
				fprintf_s(fpFile, " %12.6f ", triplets[i].variance[j]);
			}
			fprintf_s(fpFile, "\n");
		}

		// information between center point and leaf nodes
		fprintf_s(fpFile, "%12d\n", (int) LeafCenterInfo.size());
		for ( int i = 0; i < (int) LeafCenterInfo.size(); i++ )
		{
			fprintf_s(fpFile, "%12d %12.6f %12.6f \n", LeafCenterInfo[i].LeafID, LeafCenterInfo[i].ori, LeafCenterInfo[i].len);
		}

		// the stop line
		fprintf_s(fpFile, "\n");
	}

	return	1;
}

int	CAndNodeModel::ReadAndNodeModel(FILE *fpFile, int RuleCount)
{
	int		ChildCount, TripletCount, LeafNodeCount;
	int		Dim;
	char strTemp[10001];

	fscanf(fpFile, "%s%d%s%d", strTemp, &AndNodeID, strTemp, &Level);
	fscanf_s(fpFile, "%d%d%d", &NodeType, &LeafIndex, &ChildCount);

	Threshold.assign(RuleCount, 0);
	for ( int i = 0; i < RuleCount; i++ )
	{
		fscanf_s(fpFile, "%lf", &Threshold[i]);
	}

	fscanf_s(fpFile, "%lf", &AppearanceWeight);

	if ( NodeType == 1 )
	{
		Children.resize(ChildCount);
		for ( int i = 0; i < ChildCount; i++ )
		{
			fscanf_s(fpFile, "%d", &Children[i]);
		}

		fscanf_s(fpFile, "%d", &ModelCount);
		NodeModelIndex.resize(ChildCount);
		for ( int i = 0; i < (int) Children.size(); i++ )
		{
			fscanf_s(fpFile, "%d", &NodeModelIndex[i]);
		}
		NodeLenInfo.alloc(ModelCount, ModelCount);
		NodeDirInfo.alloc(ModelCount, ModelCount);
		for ( int i = 0; i < ModelCount; i++ )
		{
			for ( int j = 0; j < ModelCount; j++ )
			{
				fscanf_s(fpFile, "%lf", &NodeLenInfo[i][j]);
			}
			fprintf_s(fpFile, "\n");
		}
		for ( int i = 0; i < ModelCount; i++ )
		{
			for ( int j = 0; j < ModelCount; j++ )
			{
				fscanf_s(fpFile, "%lf", &NodeDirInfo[i][j]);
			}
			fprintf_s(fpFile, "\n");
		}

		fscanf_s(fpFile, "%d", &TripletCount);
		triplets.resize(TripletCount);
		for ( int i = 0; i < TripletCount; i++ )
		{
			fscanf_s(fpFile, "%d%d%d", &triplets[i].p1, &triplets[i].p2, &triplets[i].p3);
			fscanf_s(fpFile, "%d%d%d", &triplets[i].m1, &triplets[i].m2, &triplets[i].m3);
			fscanf_s(fpFile, "%lf", &triplets[i].gamma);
			fscanf_s(fpFile, "%d", &Dim);
			triplets[i].feature.resize(Dim);
			triplets[i].variance.resize(Dim);
			for ( int j = 0; j < Dim; j++ )
			{
				fscanf_s(fpFile, "%lf", &triplets[i].feature[j]);
			}
			for ( int j = 0; j < Dim; j++ )
			{
				fscanf_s(fpFile, "%lf", &triplets[i].variance[j]);
			}
		}

		fscanf_s(fpFile, "%d", &LeafNodeCount);
		LeafCenterInfo.resize(LeafNodeCount);
		for ( int i = 0; i < LeafNodeCount; i++ )
		{
			fscanf_s(fpFile, "%d%lf%lf", &LeafCenterInfo[i].LeafID, &LeafCenterInfo[i].ori, &LeafCenterInfo[i].len);
		}
	}

	return	1;
}